using System;
using System.Resources;
using System.Threading;
using System.Reflection;
using System.Globalization;

namespace CodePlex.Diagnostics
{
    /// <summary>
    /// Provides string resources within the CodePlex.Diagnostics framework.
    /// </summary>
    internal sealed class SR
    {
        #region SR Private Fields

        private ResourceManager m_resources;

        private static object m_internalSyncObject;

        private static SR m_instance;

        #endregion

        #region SR Internal Members

        internal const string InvalidSoapEncodedIIdentity = "InvalidSoapEncodedIIdentity";
        internal const string InvalidSoapEncodedException = "InvalidSoapEncodedException";
        internal const string InvalidLogEntry = "InvalidLogEntry";
        internal const string PublishedException = "PublishedException";
        internal const string UnhandledException = "UnhandledException";
        internal const string ThreadException = "ThreadException";
        internal const string PublicationId = "PublicationId";

        #endregion

        #region private SR()

        /// <summary>
        /// Initializes a new instance of the <see cref="T:SR"/> class.    
        /// </summary>
        private SR()
        {
#if TEST 
            // create an instance of the ResourceManager class using the base name for the resources within the CodePlex.Diagnostics.UnitTests project.
            m_resources = new ResourceManager("CodePlex.Diagnostics.UnitTests.CodePlex.Diagnostics", this.GetType().Assembly);
#else
            // create an instance of the ResourceManager class using the base name for the resources within the CodePlex.Diagnostics project.
            m_resources = new ResourceManager("CodePlex.Diagnostics.CodePlex.Diagnostics", this.GetType().Assembly); 
#endif
        }

        #endregion

        #region public static string GetString(string name)

        /// <summary>
        /// Gets the value of the <see cref="T:System.String"/> resource localized for the <see cref="M:System.Threading.Thread.CurrentUICulture"/>.
        /// </summary>
        /// <param name="name">The name of the <see cref="T:System.String"/> resource.</param>
        /// <returns>The value of the <see cref="T:System.String"/> resource localized for the <see cref="M:System.Threading.Thread.CurrentUICulture"/>.</returns>
        public static string GetString(string name)
        {
            SR sr = SR.GetInstance();
        
            if (sr == null)
            {
                return null;
            }

            return sr.ResourceManager.GetString(name, SR.Culture);
        }

        #endregion

        #region private static object InternalSyncObject

        /// <summary>
        /// Gets the internal sync object.
        /// </summary>
        /// <value>The internal sync object.</value>
        private static object InternalSyncObject
        {
            get
            {
                if (SR.m_internalSyncObject == null)
                {
                    object _object = new object();

                    Interlocked.CompareExchange(ref SR.m_internalSyncObject, _object, null);
                }
            
                return SR.m_internalSyncObject;
            }
        } 

        #endregion

        #region private static SR GetInstance()

        /// <summary>
        /// Gets an instance of the <see cref="T:CodePlex.Diagnostics.SR"/> class.
        /// </summary>
        /// <returns>An instance of the <see cref="T:CodePlex.Diagnostics.SR"/> class.</returns>
        private static SR GetInstance()
        {
            if (SR.m_instance == null)
            {
                lock (SR.InternalSyncObject)
                {
                    // use the double-check locking pattern.
                    if (SR.m_instance == null)
                    {
                        SR.m_instance = new SR();
                    }
                }
            }

            return SR.m_instance;
        }

        #endregion

        #region public ResourceManager ResourceManager

        /// <summary>
        /// Gets the <see cref="T:System.Resources.ResourceManager"/> instance.
        /// </summary>
        public ResourceManager ResourceManager
        {
            get
            {
                return m_resources;
            }
        }

        #endregion

        #region public static CultureInfo Culture

        /// <summary>
        /// Gets the <see cref="T:System.Globalization.CultureInfo"/> instance for which strings should be localized.
        /// </summary>
        /// <value>Returns the <see cref="M:System.Threading.Thread.CurrentUICulture"/>.</value>
        public static CultureInfo Culture
        {
            get
            {
                return Thread.CurrentThread.CurrentUICulture;
            }
        }

        #endregion
    }
}
